<template>
  <!-- 日历模块 -->
  <section class="calendar-view" v-loading="loading">
    <FullCalendar
      id="calendar"
      ref="calendarRef"
      :options="calendarOptions"
    ></FullCalendar>
  </section>
</template>

<script>
import '@fullcalendar/core/vdom';
import FullCalendar from '@fullcalendar/vue';
import dayGridPlugin from '@fullcalendar/daygrid'; // 月视图插件

import tippy from 'tippy.js';
import 'tippy.js/dist/tippy.css';

import lunar from '@src/modules/calendar/lunar';
import { rangeOfMonth, dayTimeEnd, dayTimeStart, formatDate, FormatTemplate } from 'pub-bbx-utils';

import i18n from '@src/locales';

// api
import { getCalendarShowView, planTaskShowView } from '@src/api/ContractApi';

import Platform from '@src/util/platform.ts';

import { safeNewDate } from '@src/util/time';
import { getRootWindow } from '@src/util/dom';
import { getThemeColor } from '@src/util/business/color'

let currentDay = safeNewDate().getDate();
let currentMonth = safeNewDate().getMonth() + 1;
let currentYear = safeNewDate().getFullYear();
import { PageRoutesTypeEnum } from 'pub-bbx-global/pageType/dist/enum/PageRoutesEnum'
const shbLocale = i18n.locale
export default {
  name: 'calendar-view',
  props: {
    source: {
      type: String,
      default: '',
    },
  },
  components: {
    FullCalendar,
  },
  data() {
    return {
      loading: false,
      calendarApi: null,
      calendarData: [],
      calendarOptions: {
        // 引入的插件
        plugins: [dayGridPlugin],
        // 指定默认显示视图
        initialView: 'dayGridMonth',
        // 切换语言，当前为中文
        locale: shbLocale,
        // 修改日程背景色
        eventColor: getThemeColor(),
        // 设置日历单元格宽度与高度的比例
        aspectRatio: 1,
        editable: false, // 是否可以进行（拖动、缩放）修改
        selectable: false, // 是否可以选中日历格
        selectMirror: true,
        // displayEventEnd: true, // 所有视图显示结束时间
        stickyHeaderDates: true,
        // 相同时间段的多个日程视觉上是否允许重叠，默认true允许
        slotEventOverlap: false,
        handleWindowResize: true, //是否随窗口大小变化
        // 头部按钮布局展示设置
        headerToolbar: {
          left: 'todayCustom title prevMonthCustom,nextMonthCustom',
          center: '',
          right: '',
        },
        // 自定义按钮
        customButtons: {
          todayCustom: {
            text: i18n.t('common.base.today'),
            click: this.handleClickTodayFn,
          },

          prevMonthCustom: {
            text: '<',
            click: this.handleClickPrevFn,
          },
          nextMonthCustom: {
            text: '>',
            click: this.handleClickNextFn,
          },
        },
        events: [],
        // 当事件过多时是否隐藏
        dayMaxEvents: true,
        // 鼠标移上去事件
        eventMouseEnter: this.handleEventMouse,
        eventClick: this.handleEventClick, // 日程点击信息展示
        eventTimeFormat: {
          // like '14:30'
          hour: '2-digit',
          minute: '2-digit',
          meridiem: false,
          hour12: false, // 设置时间为24小时
        },
        eventDidMount: this.eventDidMount,
        moreLinkDidMount: this.handleMoreLinkDidMount,
        moreLinkContent: this.handleMoreLinkContent,
        // 自定义渲染视图
        views: {
          dayGridMonth: {
            // 转农历
            dayCellContent(item) {
              let date = safeNewDate(item.date).toLocaleDateString().split('/');
              const { festival, lunarFestival, Term, IDayCn } =
                lunar.solar2lunar(date[0], date[1], date[2]);
              const f = festival || lunarFestival || Term || IDayCn;

              let htmlStr1 = '<span class="other-date-text">';
              let htmlStr2 = '<span class="other-date-text ft_12">';
              if (
                currentYear == date[0] &&
                currentMonth == date[1] &&
                currentDay == date[2]
              ) {
                htmlStr1 = '<span class="current-month-day">';
                htmlStr2 = '<span class="current-date-text">';
              }
              let htmlStr = `${htmlStr1}${date[2]}</span>`
              if( shbLocale === 'zh') {
                htmlStr = `${htmlStr}${htmlStr2}${f}</span>`
              }
              return {
                html: htmlStr,
              };
            },
          },
        },
      },
    };
  },
  computed: {
    contractId() {
      return location.pathname.split('/contract/view/')[1] || '';
    },
    // 华大基因灰度
    isBgiSaas() {
      const RootWindow = getRootWindow(window)
      return Boolean(RootWindow.grayAuth?.bgiSaas)
    }
  },
  mounted() {
    this.calendarApi = this.$refs.calendarRef.getApi();
    this.initCalendar();
  },
  methods: {
    initCalendar() {
      let params = {
        contractId: this.contractId,
      };

      let currentDate = this.calendarApi?.currentData?.currentDate;
      let timeArr = rangeOfMonth(currentDate);

      params.startDate = +dayTimeStart(timeArr[0]);
      params.endDate = +dayTimeEnd(timeArr[1]);

      this.loading = true;
      let url =
        this.source === 'plan'
          ? planTaskShowView(params)
          : getCalendarShowView(params);
      url
        .then(res => {
          this.loading = false;
          const { result = [], success } = res;

          if (!success) return Platform.toast(res.message, 'error');

          if (!result || !result.length) return;

          let events = [];
          
          result.map(item => {
            events.push(this.getEvent(item));
          });

          this.$set(this.calendarOptions, 'events', events);
          this.calendarData = events;
        })
        .catch(e => {
          this.loading = false;
        });
    },
    handleMoreLinkDidMount(info) {
      info.el.innerHTML = `<div>${info.shortText}</div>`;
    },
    handleMoreLinkContent(info) {
      info.text = '';
    },
    resizeRender() {
      this.initCalendar();
    },

    // 渲染事件
    getEvent(event) {
      let {
        id,
        calendarName,
        planTaskName,
        startTime,
        endTime,
        status,
        daySpan,
      } = event;

      const startTimeStr = formatDate(startTime);
      const endTimeStr = formatDate(endTime);

      let tempObj = {
        id,
        title: calendarName || planTaskName,
        currentId: id,
        start: daySpan
          ? formatDate(startTime, FormatTemplate.date)
          : startTimeStr,
        end: daySpan
          ? formatDate(endTime, FormatTemplate.date)
          : endTimeStr,
        startTime: startTimeStr,
        endTime: endTimeStr,
        allDay: daySpan,
      };

      // 已完成
      let cancelStyle = status == 1 ? 'event-cancle' : '';

      tempObj.classNames = ['event-cls', 'event-cls-common', cancelStyle];
      return tempObj;
    },

    // 点击今天
    handleClickTodayFn() {
      this.calendarApi.today();
      this.initCalendar();
    },

    // 点击上一个月
    handleClickPrevFn() {
      this.calendarApi.prev();
      this.initCalendar();
    },

    // 点击下一个月
    handleClickNextFn() {
      this.calendarApi.next();
      this.initCalendar();
    },

    // 鼠标放到事件上有提示
    handleEventMouse(info) {
      tippy(info.el, {
        content: info.el.innerText,
      });
    },

    // 点击跳转
    handleEventClick(info) {
      this.source === 'plan'
        ? this.jumpPlanTaskTab(info)
        : this.jumpCalendarDetail(info);
    },

    // 点击跳转日程详情页面
    jumpCalendarDetail(val) {
      const { id, start, end } = val.event;
      const startTime = safeNewDate(start).getTime();
      const endTime = safeNewDate(end).getTime();
      let fromId = window.frameElement.getAttribute('id');
      
      Platform.openAccurateTab({
        type: PageRoutesTypeEnum.PageSchedule,
        params: `id=${id}&startTime=${startTime}&endTime=${endTime}`,
        reload: true,
        fromId
      })
    },

    /** 跳转编辑计划任务 */
    jumpPlanTaskTab(val) {
      const { id } = val.event;

      let fromId = window.frameElement.getAttribute('id');

      Platform.openAccurateTab({
        type: this.isBgiSaas ? PageRoutesTypeEnum.PagePlanTaskView : PageRoutesTypeEnum.PagePlanTaskEdit,
        key: id,
        params: `id=${id}`,
        reload: true,
        fromId
      })
    },

    // 事件被渲染
    eventDidMount(info) {
      this.$nextTick(() => {
        let parentDom = info.el;
        if (parentDom.classList.contains('fc-daygrid-block-event')) {
          let dom = parentDom.getElementsByClassName('fc-event-main-frame')[0];
          let childDom = document.createElement('div');
          childDom.innerHTML =
            '<div class="fc-daygrid-event-dot"></div><div class="fc-event-time"></div>';
          // 跨天日程加上时间
          if (info.event.allDay) {
            let startTime = '';
            let id = info.event?.id || '';
            const item = this.calendarData.filter(x => {
              if (x.id == id) {
                // 因为跨天日程也可以循环
                // 如果一天里面有两个跨天(跨天循环的情况)的需要在判断开始时间是否一样才能渲染，不能通过id去唯一判断
                let segStart = x.start;
                let eventStart = DateUtil.format(
                  safeNewDate(info.event.startStr.replace(/-/g, '/')),
                  'yyyy-MM-dd'
                );
                if (segStart == eventStart) {
                  return x;
                }
              }
            });
            if (item && item.length) {
              if (item[0].startTime)
                startTime = DateUtil.format(
                  safeNewDate(item[0].startTime),
                  'HH:mm'
                );
              childDom.innerHTML = `<div class="fc-daygrid-event-dot"></div><div class="fc-event-time">${startTime}</div>`;
            }
          }
          childDom.classList.add('fc-dot-pa');
          dom.insertBefore(childDom, dom.childNodes[0]);
        }
      });
    },
  },
};
</script>
<style lang="scss" scoped>
.calendar-view {
  height: calc(100% - 120px);
  overflow-y: auto;
  padding-left: 16px;

  ::v-deep {
    // 日历样式
    .fc-theme-standard {
      .fc-scrollgrid {
        border: none;
      }
      th {
        border: none;
      }
      td {
        border: none;
        border-bottom: 1px solid #eee;
      }
      .fc-daygrid-day-top {
        align-items: center;
        flex-direction: row;
        justify-content: center;
      }
    }

    // 顶部工具栏
    .fc-header-toolbar {
      .fc-toolbar-chunk {
        display: flex;
        align-items: center;
        // 今天
        .fc-todayCustom-button {
          padding: 8px 15px;
          margin: 0 16px 0 0;
          font-size: 14px;
          border-radius: 4px;
          background: #fff;
          border: 1px solid #e0e1e2;
          box-sizing: border-box;
          color: #606266;
          cursor: pointer;
          display: inline-block;
          font-size: 14px;
          font-weight: 500;
          line-height: 14px;
          outline: none;
          text-align: center;
          transition: 0.1s;
          -webkit-appearance: none;
          -moz-user-select: none;
          -webkit-user-select: none;
          -ms-user-select: none;
          white-space: nowrap;
        }
        .fc-button-primary:focus {
          box-shadow: none;
        }
        // 2022年
        .fc-toolbar-title {
          color: #262626;
          font-size: 14px;
          font-weight: 400;
          margin: 0;
        }
        // 左右箭头
        .fc-button-group {
          margin: 0;
          .fc-button {
            border: 0;
            background: #fff;
            color: #8c8c8c;
            padding: 0;
            margin-left: 12px;
            -webkit-appearance: none;
            -moz-user-select: none;
            -webkit-user-select: none;
            -ms-user-select: none;
            white-space: nowrap;
            outline: none;
            .fc-icon {
              width: 16px;
              color: #8c8c8c;
              font-weight: 100;
              font-size: 18px;
              &:hover {
                color: $color-primary-light-6;
              }
            }
          }
        }
      }
    }

    // 日历顶部
    .fc-col-header-cell {
      font-weight: 400;
      color: #595959;
      border: none;
    }

    // 日历背景
    .fc-daygrid-day-frame {
      background: #fff;
    }

    .fc-day-today .fc-popover-body {
      .fc-more-popover-misc {
        display: flex;
        font-size: 12px;
        color: #8c8c8c;
      }
    }
    // 当天
    .current-month-day {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 24px;
      height: 24px;
      border-radius: 50%;
      font-size: 14px;
      background: $color-primary-light-6;
      color: #fff;
    }

    .current-date-text {
      padding: 4px;
      font-size: 12px;
    }

    .other-date-text {
      padding: 4px;
      color: #595959;
    }

    .ft_12 {
      font-size: 12px;
    }

    .fc-scroller-liquid-absolute {
      bottom: 0;
    }

    .fc-daygrid-block-event .fc-event-time {
      font-weight: 400;
    }
    // 事件样式
    .event-cls {
      border: none !important;
      &:hover {
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
      }
      .fc-event-main {
        min-height: 1em;
        font-weight: 400;
        color: #595959 !important;
      }
    }

    .event-cls-common {
      background: #f6ffed !important;
      border-color: transparent !important;
      &:active {
        color: #fff;
        background: #52c41a !important;
      }
      .fc-daygrid-event-dot {
        border: 3px solid rgb(76, 175, 80) !important;
        border-color: rgb(76, 175, 80) !important;
        margin: 0 4px 0 2px;
      }
    }
    .fc-dot-pa {
      display: flex;
      align-items: center;
      margin-left: 2px;
    }

    .fc-event-selected:after,
    .fc-event:focus:after {
      background: none;
    }
    .event-cls,
    .fc-event-title-container {
      .fc-event-title {
        align-items: center;
        font-weight: 400;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
        color: #595959 !important;
      }
    }
    .event-cancle {
      div {
        text-decoration: line-through;
      }
    }

    // 点击更多popover
    .fc .fc-popover {
      top: 25% !important;
      left: 25% !important;
    }
    .fc .fc-popover-body {
      max-height: 300px;
      overflow: auto;
      .fc-more-popover-misc {
        height: 30px;
        font-size: 18px;
      }
      .fc-daygrid-event-harness a {
        height: 24px;
        line-height: 24px;
      }
      .fc-event-title {
        width: 300px;
      }
    }
    .fc .fc-more-popover .fc-popover-header {
      background: #fafafa;
    }
  }
}
</style>